package com.magnificent.atlantis.server;

import com.magnificent.atlantis.common.Connector;
import com.magnificent.atlantis.common.entity.messages.*;
import com.magnificent.atlantis.server.connection.ServerConnectorImpl;
import com.magnificent.atlantis.server.database.HibernateUtil;
import com.magnificent.atlantis.server.database.message.*;
import com.magnificent.atlantis.server.resources.AtlantisServerResources;
import com.magnificent.atlantis.server.settings.SettingsStorage;
import com.magnificent.atlantis.server.ui.MainFrame;
import com.magnificent.commons.utils.resource.ResourceAllocator;
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
import org.apache.log4j.PropertyConfigurator;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * User: Babanin
 * Date: 25.03.2009
 * Time: 19:57:50
 */
public class MainLoad {
    private static final Connector connector = new ServerConnectorImpl();

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
            IllegalAccessException, UnsupportedLookAndFeelException {
        initialize();
        initializeMessageHandlers();
        initializeDB();
        initializeRMI();
        initializeUI();
    }

    private static void initializeMessageHandlers() {
        MessageHandler.register(ServerTextMessage.class, new TextMessageHandler());
        MessageHandler.register(ServerNewMeetingMessage.class, new NewMeetingMessageHandler());
        MessageHandler.register(ServerAcceptMeetingMessage.class, new AcceptMeetingMessageHandler());
        MessageHandler.register(ServerCancelMeetingMessage.class, new CancelMeetingMessageHandler());
        MessageHandler.register(ServerUpdateMeetingMessage.class, new UpdateMeetingMessageHandler());
    }

    private static void initialize() throws UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(new WindowsLookAndFeel());
        ResourceAllocator.addResourceLocationClass(AtlantisServerResources.class);
        PropertyConfigurator.configure(AtlantisServerResources.LOG4J_PROPERTIES);
    }

    private static void initializeDB() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        HibernateUtil.getSessionFactory();
    }

    private static void initializeRMI() {
        System.getProperties().setProperty("java.security.policy", "rmi.policy");
        System.getProperties().setProperty("java.rmi.server.logCalls", "true");

        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }

        try {
            Connector stub = (Connector) UnicastRemoteObject.exportObject(connector, 0);

            Registry registry = LocateRegistry.createRegistry(SettingsStorage.getSettings().getPort());
            registry.rebind(Connector.NAME, stub);

            System.out.println("AtlantisConnector bound");
        } catch (Exception e) {
            System.err.println("RMI exception:");
            e.printStackTrace();
        }
    }

    private static void initializeUI() {
        MainFrame mainFrame = new MainFrame();
        mainFrame.setVisible(true);
        mainFrame.addWindowListener(new WindowAdapter() {
            public void windowClosed(WindowEvent e) {
                finish();
            }
        });
    }

    private static void finish() {
        SettingsStorage.saveSettings();
    }
}
